<?php

namespace App\Services\YunXinCloud;


use App\Dao\ChatRoomDao;
use App\Event\KickMemberNotify;
use App\Event\MicrophoneNotify;
use App\Event\MuteRoomNotify;
use App\Event\UpdateRoomNotify;
use App\Exception\MessageException;
use App\Model\ChatRoom;
use App\Model\ChatRoomUser;
use App\Model\ChatRoomMicrophone;
use App\Model\User;
use App\Services\Chat\ChatUserService;
use App\Services\Chat\MicroPhoneService;
use App\Utils\LoggerUtil;
use Hyperf\DbConnection\Db;
use Hyperf\Di\Annotation\Inject;
use Psr\EventDispatcher\EventDispatcherInterface;

class WyyChatRoomService extends WyyClient
{
    #[Inject]
    public WyyChatRoomClient $client;

    #[Inject]
    public ChatUserService $chatUserService;

    #[Inject]
    public MicroPhoneService $microPhoneService;

    #[Inject]
    public EventDispatcherInterface $eventDispatcher;


    /**
     * Note - 获取聊天室列表
     * DateTime 2024/8/30 12:42
     * User Admin
     * @param $params
     * @return array
     */
    public function getRoomList($params)
    {
        $type = $params['type'] ?? 0;
        $page = $params['page'] ?? 1;
        $pageSize = $params['pageSize'] ?? 10;
        $data = ChatRoomDao::getInstance()->getRoomList($type, $page, $pageSize);
        return formatData(['result' => 1, 'msg' => $data]);
    }

    /**
     * Note - 创建聊天室
     * DateTime 2024/8/30 11:46
     * User Admin
     * @param $userInfo
     * @param $params
     * @return array
     */
    public function createChatRoom($userInfo, $params)
    {
        $accid = $userInfo['id'];
        $name = $params['name'];
        $announcement = $params['announcement'] ?? '';
        $ext = $params['ext'] ?? [];
        $queuelevel = $params['queuelevel'] ?? 1;
        $inOutNotification = $params['inOutNotification'] ?? 1;
        $data = $this->client->createChatRoom($accid, $name, $announcement, $ext, $queuelevel, $inOutNotification);

        if (ChatRoom::query()->where('uid', $accid)->exists()) {
            ChatRoom::query()->where('uid', $accid)->update(['room_id' => $data['roomid']]);
            return formatData([
                'result' => 1,
                'msg' => ['room_id' => $data['roomid'], 'room_number' => $accid]
            ]);
        }

        try {
            Db::beginTransaction();
            $roomInfo['uid'] = $accid;
            $roomInfo['room_id'] = $data['roomid'];
            $roomInfo['room_number'] = $accid;
            $roomInfo['name'] = $params['name'];
            $roomInfo['img_face'] = $params['img_face'] ?? $userInfo['head_image'];
            $roomInfo['level'] = 1;          //等级
            $roomInfo['room_all_cost'] = 0;       // 房间内用户消费金币数
            $roomInfo['label'] = $params['label'] ?? '其他';        //标签
            $roomInfo['theme'] = $params['theme'] ?? '沙漠';        //主题
            $roomInfo['notice'] = $params['announcement'] ?? '';    //公告
            $roomInfo['microphone'] = 5;     //麦位 5个
            $roomInfo['istop'] = 0;          //是否置顶
            $roomInfo['status'] = 0;         //房间状态 0正常 1封禁
            $roomInfo['ctime'] = time();
            $roomInfo['count_user'] = 0;     //房间人数
            $roomInfo['count_current'] = 0;  //当前人数
            // $roomInfo['broadcasturl'] = $data['broadcasturl'];  // 直播地址
            $roomInfo['muted'] = $data['muted'];  // 聊天室是否处于全体禁言状态，全体禁言时仅管理员和创建者可以发言，false：未禁言，ture：禁言
            $roomInfo['ext'] = $data['ext'];  // 扩展字段
            $roomInfo['valid'] = $data['valid'];  // false：聊天室关闭，true：聊天室开放
            $roomInfo['queuelevel'] = $data['queuelevel'];  // 队列管理权限。0：所有人都有权限变更队列，1：只有主播管理员才能操作变更
            ChatRoom::query()->insert($roomInfo);

            //添加房间用户:房主
            $roomUser['uid'] = $accid;
            $roomUser['room_number'] = $accid;
            $roomUser['mi_seq'] = -1;       //上麦麦位  0-4麦位; -1:未上麦
            $roomUser['status'] = 2;        //状态 0正常 1封禁 2永久封禁
            $roomUser['enter_time'] = 0;    //进入时间
            $roomUser['in_room'] = 1;       //是否在房间里
            $roomUser['enter_time'] = time();
            $roomUser['unblock_time'] = 0;  //解封时间
            $roomUser['ctime'] = time();
            ChatRoomUser::query()->insert($roomUser);

            // 创建麦位
            for ($i = 0; $i < $roomInfo['microphone']; $i++) {
                $miInfo['room_number'] = $accid;
                $miInfo['mi_seq'] = $i;
                $miInfo['mi_seq_lock'] = 0;// 0-正常；1-锁定
                $miInfo['mi_up_down'] = 0;// 用户是否在麦位：0-否；1-是
                ChatRoomMicrophone::query()->insert($miInfo);
            }


            Db::commit();
            return formatData([
                'result' => 1,
                'msg' => ['room_id' => $data['roomid'], 'room_number' => $accid]
            ]);

        } catch (\Throwable $e) {
            Db::rollBack();
            LoggerUtil::write('create_chatroom', $e->getMessage());
            throw new MessageException('创建聊天室失败！');
        }


    }


    /**
     * Note - 获取聊天室信息
     * DateTime 2024/8/30 11:47
     * User Admin
     * @param $params
     * @return array
     */
    public function showChatRoom($params)
    {
        $room_number = $params['room_number'];
        $data = ChatRoomDao::getInstance()->showChatRoom($room_number);
        // 获取在聊天室的用户列表
        $data['room_user'] = $this->chatUserService->getInRoomUserList($room_number);
        $data['mi_info'] = $this->microPhoneService->getMiInfo($room_number);
        if (!$data) {
            throw new MessageException('聊天室不存在！');
        }
        return formatData([
            'result' => 1,
            'msg' => $data
        ]);
    }


    /**
     * 更新聊天室
     * @param $params
     * @return mixed
     */
    public function updateChatRoom($params)
    {
        $room_number = $params['room_number'];
        $data = ChatRoom::query()->where('room_number', $room_number)->first();
        if (!$data) {
            throw new MessageException('聊天室不存在！');
        }
        $name = $params['name'] ?? $data['name'];
        $announcement = $params['announcement'] ?? $data['announcement'];
        $ext = $params['ext'] ?? json_decode($data['ext']);
        $queuelevel = $params['queuelevel'] ?? $data['queuelevel'];
        $needNotify = $params['needNotify'] ?? 'false';
        $chatroom = $this->client->updateChatRoom($data['room_id'], $name, $announcement, $ext, $needNotify, $queuelevel);

        $update['uid'] = $chatroom['creator'];
        $update['room_id'] = $chatroom['roomid'];
        $update['valid'] = $chatroom['valid'];
        $update['notice'] = $chatroom['announcement'];
        $update['name'] = $chatroom['name'];
        // $update['broadcasturl'] = $chatroom['broadcasturl'];
        $update['ext'] = $chatroom['ext'];
        ChatRoom::query()->where('room_number', $room_number)->update($update);

        $this->eventDispatcher->dispatch(new UpdateRoomNotify($update, $data['room_id']));
        $update['room_number'] = $room_number;
        return formatData(['result' => 1, 'msg' => $update]);
    }


    /**
     * Note -开放/关闭聊天室
     * DateTime 2024/8/30 15:11
     * User Admin
     * @param $room_number
     * @param $operator
     * @param $valid
     * @return array
     */
    public function toggleCloseStat($room_number, $operator, $valid)
    {
        $roomId = ChatRoom::query()->where('room_number', $room_number)->value('room_id');
        $data = $this->client->toggleCloseStat($roomId, $operator, $valid);
        $data['notice'] = intval($data['announcement']);
        $data['room_id'] = intval($data['roomid']);
        $data['uid'] = $data['creator'];
        $data['ext'] = json_decode($data['ext']);
        unset($data['announcement']);
        unset($data['roomid']);
        unset($data['creator']);
        ChatRoom::query()->where('room_number', $room_number)->update(['valid' => $data['valid']]);
        $data['room_number'] = $room_number;
        return formatData(['result' => 1, 'msg' => $data]);
    }


    /**
     * Note - 设置聊天室成员角色
     * DateTime 2024/8/30 15:40
     * User Admin
     * @param $params
     * @return array
     */
    public function setMemberRole($params): array
    {
        $room_number = $params['room_number'];
        $roomId = ChatRoom::query()->where('room_number', $room_number)->value('room_id');
        $operator = $params['operator'];
        $target = $params['target'];
        $opt = $params['opt'];
        $optvalue = $params['optvalue'] == 'true';

        $data = $this->client->setMemberRole($roomId, $operator, $target, $opt, $optvalue);
        if (!$params['optvalue']) {
            $optv = 0;
        } else {
            $optv = $opt;
        }
        if ($data['type'] != 'LIMITED') {
            ChatRoomUser::query()->where('room_number', $room_number)->where('uid', $target)->update(['opt' => $optv]);
        }
        return formatData($data);
    }


    /**
     * Note - 踢人出聊天室
     * DateTime 2024/9/3 12:28
     * User Admin
     * @param mixed $params
     * @return bool
     */
    public function kickMember($params)
    {
        $room_number = $params['room_number'];
        $operator = $params['uid'];
        $target = $params['target'];
        $roomId = ChatRoom::query()->where('room_number', $room_number)->value('room_id');
        $result = $this->client->kickMember($roomId, $operator, $target);
        if ($result) {
            ChatRoomUser::query()->where('room_number', $room_number)->where('uid', $target)->update(['in_room' => 0]);
            $userInfo = User::query()->where('id', $target)->select(['id', 'nickname', 'head_image', 'sex', 'age', 'noble', 'wealth'])->first();
            if ($userInfo) {
                $userInfo = modelToArray($userInfo);
                $this->eventDispatcher->dispatch(new KickMemberNotify($userInfo, $operator, $roomId));

                $miSeq = ChatRoomMicrophone::query()->where('room_number', $room_number)->where('uid', $target)->value('mi_seq');
                if ($miSeq) {
                    $mic = modelToArray($miSeq);
                    ChatRoomMicrophone::query()->where('room_number', $room_number)->where('uid', $target)->update(['mi_up_down' => 0, 'u_voice_status' => 1, 'a_voice_status' => 1]);
                    $data = $this->microPhoneService->getMicUserInfo($room_number, $mic['mi_seq']);
                    $microInfo = $data['microInfo'];
                    $microInfo['room_id'] = $roomId;
                    $userInfo = $data['userInfo'];
                    $this->eventDispatcher->dispatch(new MicrophoneNotify($microInfo, $userInfo, $operator));
                }

            }
            return true;
        } else {
            return false;
        }
    }

    /**
     * Note - 禁言聊天室成员
     * DateTime 2024/9/3 14:59
     * User Admin
     * @param $params
     * @return true
     */
    public function muteMember($params)
    {
        $room_number = $params['room_number'];
        $roomId = ChatRoom::query()->where('room_number', $room_number)->value('room_id');
        $operator = $params['uid'];
        $target = $params['target'];
        $muteDuration = $params['duration'];
        return $this->client->muteMember($roomId, $operator, $target, $muteDuration);

    }

    /**
     * Note - 禁言聊天室
     * DateTime 2024/9/3 14:59
     * User Admin
     * @param $params
     * @return true
     */
    public function muteRoom($params)
    {
        $room_number = $params['room_number'];
        $roomId = ChatRoom::query()->where('room_number', $room_number)->value('room_id');
        $operator = $params['uid'];
        $mute = $params['mute'];
        $result = $this->client->muteRoom($roomId, $operator, $mute);
        if ($result) {
            // ChatRoomMicrophone::query()->where('room_id', $roomId)->update(['a_voice_status' => 0]);
            $this->eventDispatcher->dispatch(new MuteRoomNotify($roomId, $operator));
        }
    }

}